package com.xzzz.irda.auth.server;

import com.xzzz.irda.auth.core.AuthBaseConfiguration;
import com.xzzz.irda.auth.core.token.DefaultTokenGenerator;
import com.xzzz.irda.auth.core.token.PasswordEncoder;
import com.xzzz.irda.auth.core.util.SHA256PasswordEncoder;
import com.xzzz.irda.auth.core.token.TokenGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

/**
 * 服务端配置类, 继承 {@link AuthBaseConfiguration}
 * <p>
 * 注入方式
 *
 * @author wangyf
 * @see EnableAuthServer
 * 
 */
@Slf4j
@Configuration
public class AuthServerConfiguration extends AuthBaseConfiguration {

    /**
     * Token生成器
     */
    private volatile TokenGenerator tokenGenerator;

    /**
     * 加密方式
     */
    private volatile PasswordEncoder passwordEncoder;

    /**
     * 获取 token 生成方式, 如果未自定则使用默认方式 {@link DefaultTokenGenerator}
     * 若未注入则登录时初始化,可能存在多线程创建覆盖,双检索单例
     *
     * @return TokenGenerator
     */
    public TokenGenerator getTokenGenerator() {
        if (tokenGenerator == null) {
            synchronized (DefaultTokenGenerator.class) {
                if (tokenGenerator == null) {
                    tokenGenerator = new DefaultTokenGenerator();
                }
            }
        }
        return tokenGenerator;
    }

    /**
     * 自动注入 token 生成实现类, 自定义时需要注入到容器中
     *
     * @param tokenGenerator token 生成实现类
     */
    @Autowired(required = false)
    public void setTokenGenerator(TokenGenerator tokenGenerator) {
        this.tokenGenerator = tokenGenerator;
    }


    /**
     * 获取密码加密方式
     * 若未注入则登录时初始化,可能存在多线程创建覆盖,双检索单例
     *
     * @return 密码加密实现类
     */
    public PasswordEncoder getPasswordEncoder() {
        if (passwordEncoder == null) {
            synchronized (DefaultTokenGenerator.class) {
                if (passwordEncoder == null) {
                    passwordEncoder = new SHA256PasswordEncoder();
                }
            }
        }
        return passwordEncoder;
    }


    @Autowired(required = false)
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

}
